package ae.pcfc.etks.online.common.util;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class CommonUtils {

	public static final String USER_PREFIX = "group.root.ad/";

	public static String appendDomainPrefix(String userName) {
		if (userName == null) {
			return null;
		} else if (!userName.contains(USER_PREFIX)) {
			return USER_PREFIX + userName;
		} else {
			return userName;
		}
	}

	public static Date getDateFromString(String date) {

		try {
			SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
			return df.parse(date);
		} catch (ParseException ex) {
			return null;
		}
	}

	/**
	 * getCurrentDateAsDDMMYYYY Method to get current date in the format
	 * dd/MM/yyyy
	 * 
	 * @return String
	 */
	public static String getCurrentDateAsDDMMYYYY() {

		Date date = new Date();
		// Keep the MM upper case
		SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
		String formattedDate = df.format(date);
		return formattedDate;

	}

	@SuppressWarnings("unchecked")
	public static void sort(Collection<?> collection, String field,
			boolean sortAsc) {
		Collections.sort((List<?>) collection, new DynamicComparator(field,
				sortAsc));
	}

	@SuppressWarnings("unchecked")
	public static void sort(Collection<?> collection, String field,
			boolean sortAsc, boolean stringAsNumber) {
		Collections.sort((List<?>) collection, new DynamicComparator(field,
				sortAsc, stringAsNumber));
	}

	@SuppressWarnings("unchecked")
	public static void sort(Object[] objects, boolean sortAsc) {
		Arrays.sort(objects, new DynamicComparator(sortAsc));
	}

	@SuppressWarnings("unchecked")
	public static <T> void sort(T[] objects, boolean sortAsc,
			final boolean stringAsNumber) {
		Arrays.sort(objects, new DynamicComparator(sortAsc, stringAsNumber));
	}

	public static String getStringFieldValue(Object o, String field) {
		Object retVal = getFieldValue(o, field);
		if (retVal != null) {
			return (String) retVal;
		}
		return "";
	}

	public static Object getFieldValue(Object o, String field) {
		try {
			if (o != null && field != null) {
				Class c = o.getClass();
				if (c != null) {
					Field f = c.getDeclaredField(field);
					if (f != null) {
						f.setAccessible(true);
						return f.get(o);
					}
				}
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static Long getLongFieldValue(Object o, String field) {
		String value = (String) getFieldValue(o, field);
		if (value != null) {
			try {
				Long longValue = Long.parseLong(value);
				return longValue;
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		return new Long(0);
	}

	/**
	 * union Method to combine two lists
	 * 
	 * @param list1
	 * @param list2
	 * @return List
	 */
	public static List union(final List list1, final List list2) {
		final ArrayList result = new ArrayList(list1);

		final Iterator iterator = list2.iterator();
		while (iterator.hasNext()) {
			final Object o = iterator.next();
			if (!result.contains(o)) {
				result.add(o);
			}
		}

		return result;
	}

	/**
	 * subtract Method to subtract two lists - List2 from List1
	 * 
	 * @param list1
	 * @param list2
	 * @return List
	 */
	public static List subtract(final List list1, final List list2) {
		final ArrayList result = new ArrayList();
		if (list2 == null) {
			return list1;
		}
		final Iterator iterator = list1.iterator();
		while (iterator.hasNext()) {
			final Object o = iterator.next();
			if (!list2.contains(o)) {
				result.add(o);
			}
		}

		return result;
	}

}
